package com.evil.application.enums.reporting;

import cn.hutool.core.collection.ListUtil;
import com.evil.application.enums.form.control.ControlCodeEnum;
import com.evil.application.pojo.dto.reporting.ReportingTargetDTO;
import com.evil.common.application.dto.form.control.ControlBaseDTO;
import com.evil.common.core.enums.BaseEnum;
import com.evil.common.family.enums.RCodeEnum;
import com.evil.common.core.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * 报表指标类型
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@AllArgsConstructor
public enum ReportingTargetTypeEnum {

    /**
     * 报表指标类型
     */
    CONTROL(0, "控件", 1),
    FORMULA(1, "通过计算获得指标", 0),
    DATA_SUMMARY(2, "数据总量", 2),
    PROCESS_HANDLE_TIME(3, "流程处理时长", 3),
    PROCESS_OVERTIME_TIME(4, "流程超时时长", 4),
    ;

    @Getter
    private final int id;
    @Getter
    private final String name;
    @Getter
    private final int sort;

    public ReportingTargetDTO target() {
        ReportingTargetDTO reportingTargetDTO = new ReportingTargetDTO().setTargetType(this.id);
        reportingTargetDTO.setTitle(this.name);
        return reportingTargetDTO;
    }

    public static Optional<ReportingTargetTypeEnum> findById(Integer id) {
        if (Objects.isNull(id)) {
            return Optional.empty();
        }
        return Arrays.stream(values()).filter(e -> e.id == id).findFirst();
    }

    public static ReportingTargetTypeEnum isExistById(Integer id) {
        return ReportingTargetTypeEnum.findById(id).orElseThrow(()
                -> new BusinessException(BaseEnum.ERROR_PARAMETER, "报表指标类型参数错误"));
    }

    public static Stream<ReportingTargetTypeEnum> stream() {
        return Arrays.stream(values());
    }

    public static void forEach(Consumer<ReportingTargetTypeEnum> action) {
        Arrays.stream(values()).sorted(Comparator.comparingInt(ReportingTargetTypeEnum::getSort)).forEach(action);
    }

    /**
     * 可以作为指标的控件类型
     *
     * @return List
     */
    public static List<String> canBeTargetCodes() {
        return ListUtil.toList(
                ControlCodeEnum.INPUT_NUMBER.getCode()
        );
    }

    public static List<ReportingTargetDTO> types(List<ControlBaseDTO> controls) {
        List<ReportingTargetDTO> types = new ArrayList<>();
        ReportingTargetTypeEnum.forEach(em -> {
            if (CONTROL.id == em.id) {
                // 过滤 可以作为指标的控件类型
                types.addAll(controls.stream()
                        .filter(e -> ReportingTargetTypeEnum.canBeTargetCodes().contains(e.getControlCode()))
                        .map(e -> {
                            ReportingTargetDTO target = em.target();
                            target.setControlId(e.getControlId());
                            target.setTitle(e.getControlTitle());
                            return target.setControlCode(e.getControlCode());
                        })
                        .toList());
            } else {
                ReportingTargetDTO target = em.target();
                if (DATA_SUMMARY.id == em.getId()) {
                    target.setSummaryType(SummaryTypeEnum.COUNT.getId());
                }
                types.add(target);
            }
        });
        return types;
    }
}
